package org.gap.wizards.world.actions;

import org.gap.wizards.pc.PlayerCharacter;
import org.gap.wizards.pc.Skill;
import org.gap.wizards.pc.skills.Challenge;
import org.gap.wizards.pc.skills.ResultType;
import org.gap.wizards.spells.Spell;
import org.gap.wizards.views.MessageOutput;
import org.gap.wizards.views.SpellSelectionView;
import org.gap.wizards.views.ViewPlatform;
import org.gap.wizards.world.Location;
import org.gap.wizards.world.MapContainer;
import org.gap.wizards.world.WorldAction;

public class CastSpellAction implements WorldAction {
	private SpellSelectionView spellView;
	private final PlayerCharacter pc;
	private final MapContainer maps;
	private final MessageOutput output;
	private final ViewPlatform console;

	public CastSpellAction(MapContainer maps, PlayerCharacter pc, SpellSelectionView view, MessageOutput output, ViewPlatform console) {
		this.maps = maps;
		this.pc = pc;
		this.spellView = view;
		this.output = output;
		this.console = console;
	}

	@Override
	public void perform() {
		spellView.setItems(pc.getSpellBook());
		console.saveBuffer();
		final Spell spell = spellView.getSelection();
		console.restore();
		if (spell != null) {
			Challenge challenge = new SpellCastChallenge(spell, pc);
			Location location = maps.activeMap();
			output.addMessage(spell.cast(location, challenge));
			spell.showAffect(location, console);
			spell.costOfSpell(pc);
		}
	}

	private static final class SpellCastChallenge implements Challenge {
		private final Spell spell;
		private final PlayerCharacter pc;

		private SpellCastChallenge(Spell spell, PlayerCharacter pc) {
			this.spell = spell;
			this.pc = pc;
		}

		@Override
		public ResultType perform() {
			Skill skill = pc.getSkill(spell.name());
			ResultType resultType = skill.rollWithModifier(0);
			return resultType;
		}
	}
}
